#include "../../include/Logger.h"
#include "../../include/Configuration.h"
#include <log4cpp/PatternLayout.hh>
#include <log4cpp/Priority.hh>
#include <log4cpp/OstreamAppender.hh>
#include <log4cpp/FileAppender.hh>
#include <iostream>
#include <algorithm>
#include <string>
#include <cctype>
#include <cstring>

using std::cout;
using std::endl;
using std::string;

using namespace log4cpp;

Mylogger *Mylogger::_pInstance = nullptr;
pthread_once_t Mylogger::_once = PTHREAD_ONCE_INIT;

Mylogger *Mylogger::getInstance() {
    pthread_once(&_once, init);
    return _pInstance;
}

void Mylogger::init() {
    _pInstance = new Mylogger();
    atexit(destroy);
}

void Mylogger::destroy() {
    if(_pInstance) {
        delete _pInstance;
        _pInstance = nullptr;
    }
}

bool compareStringWithCString(const string& str, const char* cstr) {
    // 将str1转换为小写
    string strLower = str;
    transform(strLower.begin(), strLower.end(), strLower.begin(), tolower);
    // 比较转换后的字符串和cstr是否相等
    return strcmp(strLower.c_str(), cstr) == 0;
}

Mylogger::Mylogger()
: _mycat(Category::getRoot().getInstance("SearchEngine"))
{
    /* cout << "Mylogger()" << endl; */

    // 日志的格式
    PatternLayout *pl1 = new PatternLayout();
    pl1->setConversionPattern("%d %c [%p] %m%n");
    PatternLayout *pl2 = new PatternLayout();
    pl2->setConversionPattern("%d %c [%p] %m%n");

    // 日志的目的地
    OstreamAppender *oa = new OstreamAppender("OstreamAppender", &cout);
    oa->setLayout(pl1);
    FileAppender *fa = new FileAppender("FileAppender", "../log/search.log");
    fa->setLayout(pl2);

    // 添加日志目的地到Category
    _mycat.addAppender(oa);
    _mycat.addAppender(fa);

    // 日志优先级
    string level = Configuration::getInstance()->getConfigValue("LOG_LEVEL");
    if(compareStringWithCString(level, "debug")) {
        _mycat.setPriority(Priority::DEBUG);
    } else if(compareStringWithCString(level, "info")) {
        _mycat.setPriority(Priority::INFO);
    } else if(compareStringWithCString(level, "warn")) {
        _mycat.setPriority(Priority::WARN);
    } else if(compareStringWithCString(level, "error")) {
        _mycat.setPriority(Priority::ERROR);
    } else {
        _mycat.setPriority(Priority::DEBUG);
    }
}

Mylogger::~Mylogger() {
    /* cout << "~Mylogger()" << endl; */
    Category::shutdown();
}

